#ifndef __MVT_IFAIL_CHECK_H__
#define __MVT_IFAIL_CHECK_H__

#include "mvdef.h"

#define iftrans(a)     ((mv_vptr_t)(long)(#a[0] ? a : 0))
#define ifarg2(a, ...) iftrans(a), iftrans(__VA_ARGS__)
#define ifarg1(a, ...) iftrans(a), ifarg2(__VA_ARGS__)
#define ifarg(a, ...)  iftrans(a), ifarg1(__VA_ARGS__) 

typedef struct __ifail_args {
    mv_void_t (*f_uninit)(mv_vptr_t, mv_vptr_t, mv_vptr_t);
    mv_vptr_t p_handle1;
    mv_vptr_t p_handle2;
    mv_vptr_t p_handle3;
} ifail_args_t, *ifail_args_p;

typedef struct __ifail_info {
    mv_u8_t   _u8_max;
    mv_u8_t   _u8_top;
    ifail_args_t _stru_args[0];
} ifail_info_t, *ifail_info_p;

/**
 *  用法 : ifail_init( 最大入栈的反初始化函数的数量 )
 *  描述 : 开辟供 ifail 存放反初始化函数指针及其参数的栈空间
 *  注意 : 如果开辟的空间数量少于实际使用, 则可能会导致后面的反初始化函数注册失败, 从而导致内存泄露! 
 */
#define ifail_init(NUM) struct {     \
    ifail_info_t _stru_info;         \
    ifail_args_t _stru_args[NUM];    \
} __ifail_recorde__;                 \
  __ifail_recorde__._stru_info._u8_max = NUM; \
  __ifail_recorde__._stru_info._u8_top = 0;

/**
 * 用法 : ifail ( 逻辑判断, 反初始化函数, 反初始化函数的参数... )
 * 描述 : 当逻辑判断为假时, 对反初始化函数和其参数进行入栈记录
 *       当逻辑判断为真时, 以出栈的方式依次调用反初始化函数
 */
#define ifail(expression, ...) mvt_ifail_stack((ifail_info_p)&__ifail_recorde__, expression, &(ifail_args_t){ ifarg(__VA_ARGS__) } ); \
                               if (expression)

/* 主要实现函数 */
mv_s32_t mvt_ifail_stack(ifail_info_p pstru_info, mv_u8_t u8_expression, ifail_args_p pstru_args);

#endif 
